package cs.android.view;

import static cs.android.lang.AndroidLang.event;
import static cs.java.lang.Lang.fire;
import static cs.java.lang.Lang.info;
import static cs.java.lang.Lang.no;

import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import cs.android.viewbase.ActivityViewBase;
import cs.android.viewbase.ViewPresenterImpl;
import cs.java.collections.List;
import cs.java.event.Event;
import cs.java.event.Job;

public class LoadNextListAdapter extends ActivityViewBase {

	private final Event<Void> onLoadNext = event();
	private final ViewPresenterImpl loadView;
	private EndlessScrollListener scrollListener;
	private boolean loading;

	public <T> LoadNextListAdapter(DataListPresenter<T> parent, int loadViewLayout) {
		super(parent);
		loadView = new ViewPresenterImpl(this, loadViewLayout);
		Event<List<T>> onLoad = parent.getOnLoad();
		new Job<List<T>>(onLoad) {
			public void run() {
				onListLoad(argument);
			}
		};
	}

	@Override protected void onResume() {
		super.onResume();
		updateScrollListener();
	}

	private void onListLoad(List<?> data) {
		if (no(scrollListener)) scrollListener = new EndlessScrollListener();
		else {
			loading = false;
			asListView().removeFooterView(loadView.asView());
			if (data.isEmpty()) scrollListener = null;
		}
		updateScrollListener();
	}

	private void onLoadNext() {
		fire(onLoadNext);
		loading = true;
		asListView().addFooterView(loadView.asView());
	}

	private void updateScrollListener() {
		asListView().setOnScrollListener(scrollListener);
	}

	public Event<?> getOnLoadNext() {
		return onLoadNext;
	}

	public class EndlessScrollListener implements OnScrollListener {

		private int visibleThreshold = 3;

		public EndlessScrollListener() {}

		public EndlessScrollListener(int visibleThreshold) {
			this.visibleThreshold = visibleThreshold;
		}

		public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
				int totalItemCount) {
			if (totalItemCount == 0 || loading) return;
			if (totalItemCount - visibleItemCount <= firstVisibleItem + visibleThreshold) {
				info("loading");
				onLoadNext();
			}
		}

		public void onScrollStateChanged(AbsListView view, int scrollState) {}
	}
}
